package io.smartcat.migration; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import org.cassandraunit.CQLDataLoader; import org.cassandraunit.dataset.cql.ClassPathCQLDataSet; import org.cassandraunit.utils.EmbeddedCassandraServerHelper; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; import io.smartcat.migration.MigrationEngine.Migrator; import io.smartcat.migration.migrations.schema.AddBookGenreFieldMigration; import io.smartcat.migration.migrations.schema.AddBookISBNFieldMigration; public class MigratorTest extends BaseTest { private static final Logger LOGGER = LoggerFactory.getLogger(MigratorTest.class); private static final String CONTACT_POINT = "localhost"; private static final int PORT = 9142; private static final String KEYSPACE = "migration_test_books"; private static final String CQL = "books.cql"; private static Session session; private static Cluster cluster; private CassandraVersioner versioner; private Migrator migrator; private CassandraMetadataAnalyzer metadataAnalyzer; @BeforeClass public static void init() throws Exception { LOGGER.info("Starting embedded cassandra server"); EmbeddedCassandraServerHelper.startEmbeddedCassandra("another-cassandra.yaml"); LOGGER.info("Connect to embedded db"); cluster = Cluster.builder().addContactPoints(CONTACT_POINT).withPort(PORT).build(); session = cluster.connect(); } @Before public void setUp() throws Exception { LOGGER.info("Initialize keyspace"); final CQLDataLoader cqlDataLoader = new CQLDataLoader(session); cqlDataLoader.load(new ClassPathCQLDataSet(CQL, false, true, KEYSPACE)); versioner = new CassandraVersioner(session); migrator = MigrationEngine.withSession(session); metadataAnalyzer = new CassandraMetadataAnalyzer(session); } @AfterClass public static void tearDown() { if (cluster != null) { cluster.close(); cluster = null; } } @Test public void executeOneMigration() throws Exception { assertTableDoesntContainsColumns("books", "genre"); final MigrationResources resources = new MigrationResources(); resources.addMigration(new AddBookGenreFieldMigration(1)); migrator.migrate(resources); assertTableContainsColumns("books", "genre"); } @Test public void executeTwoMigrations() throws Exception { assertTableDoesntContainsColumns("books", "genre", "isbn"); final MigrationResources resources = new MigrationResources(); resources.addMigration(new AddBookGenreFieldMigration(1)); resources.addMigration(new AddBookISBNFieldMigration(2)); migrator.migrate(resources); assertTableContainsColumns("books", "genre", "isbn"); } @Test public void updateVersionAfterMigration() throws Exception { int versionBeforeMigration = getCurrentVersion(); Migration migration = new AddBookGenreFieldMigration(1); final MigrationResources resources = new MigrationResources(); resources.addMigration(migration); migrator.migrate(resources); // verify assertThat(getCurrentVersion(), not(is(versionBeforeMigration))); assertThat(getCurrentVersion(), is(migration.getVersion())); } @Test public void skipMigrationWithVersionOlderThanCurrentSchemaVersion() throws Exception { Migration migrationWithNewerVersion = new AddBookGenreFieldMigration(2); Migration migrationWithOlderVersion = new AddBookISBNFieldMigration(1); final MigrationResources resources = new MigrationResources(); resources.addMigration(migrationWithNewerVersion); resources.addMigration(migrationWithOlderVersion); migrator.migrate(resources); // verify assertThat(getCurrentVersion(), is(migrationWithNewerVersion.getVersion())); assertTableDoesntContainsColumns("books", "isbn"); } @Test public void skipMigrationWithSameVersionThanCurrentSchemaVersion() throws Exception { int versionBeforeMigration = getCurrentVersion(); final MigrationResources resources = new MigrationResources(); resources.addMigration(new AddBookGenreFieldMigration(versionBeforeMigration)); migrator.migrate(resources); // verify assertThat(getCurrentVersion(), is(versionBeforeMigration)); } private int getCurrentVersion() { return versioner.getCurrentVersion(MigrationType.SCHEMA); } private void assertTableDoesntContainsColumns(String table, String... columns) { for (String column : columns) { assertFalse(metadataAnalyzer.columnExistInTable(column, table)); } } private void assertTableContainsColumns(String table, String... columns) { for (String column : columns) { assertTrue(metadataAnalyzer.columnExistInTable(column, table)); } } }